"""日志工厂类
提供统一的日志记录器创建和管理功能
"""

import logging
import logging.handlers
import json
from datetime import datetime
from pathlib import Path
from typing import Optional, Dict, Any
from config.log_settings import (
    DEFAULT_LOG_CONFIG, LOG_LEVELS, LOG_CATEGORIES, 
    LOG_FORMATS, ColoredFormatter, CategoryFilter
)

class JSONFormatter(logging.Formatter):
    """JSON格式化器"""
    
    def format(self, record):
        log_entry = {
            'timestamp': datetime.fromtimestamp(record.created).isoformat(),
            'level': record.levelname,
            'category': getattr(record, 'category', 'UNKNOWN'),
            'module': record.name,
            'message': record.getMessage(),
            'filename': record.filename,
            'lineno': record.lineno
        }
        
        # 添加额外字段
        if hasattr(record, 'extra_data'):
            log_entry['extra'] = record.extra_data
        
        return json.dumps(log_entry, ensure_ascii=False)

class LoggerFactory:
    """日志记录器工厂"""
    
    _loggers: Dict[str, logging.Logger] = {}
    _handlers_created = False
    
    @classmethod
    def get_logger(cls, name: str, category: str = 'SYSTEM') -> logging.Logger:
        """获取日志记录器"""
        logger_key = f"{name}_{category}"
        
        if logger_key not in cls._loggers:
            cls._loggers[logger_key] = cls._create_logger(name, category)
        
        return cls._loggers[logger_key]
    
    @classmethod
    def _create_logger(cls, name: str, category: str) -> logging.Logger:
        """创建日志记录器"""
        logger = logging.getLogger(name)
        logger.setLevel(LOG_LEVELS.get(DEFAULT_LOG_CONFIG['level'], logging.INFO))
        
        # 避免重复添加处理器
        if not logger.handlers:
            cls._setup_handlers(logger, category)
        
        return logger
    
    @classmethod
    def _setup_handlers(cls, logger: logging.Logger, category: str):
        """设置日志处理器"""
        log_dir = Path(DEFAULT_LOG_CONFIG['log_dir'])
        log_dir.mkdir(exist_ok=True)
        
        # 控制台处理器
        if DEFAULT_LOG_CONFIG['console_output']:
            console_handler = logging.StreamHandler()
            console_handler.setLevel(logging.INFO)
            
            if DEFAULT_LOG_CONFIG['json_format']:
                console_formatter = JSONFormatter()
            else:
                console_formatter = ColoredFormatter(LOG_FORMATS['standard'])
            
            console_handler.setFormatter(console_formatter)
            logger.addHandler(console_handler)
        
        # 文件处理器
        file_handler = logging.handlers.RotatingFileHandler(
            filename=log_dir / 'app.log',
            maxBytes=DEFAULT_LOG_CONFIG['max_file_size'],
            backupCount=DEFAULT_LOG_CONFIG['backup_count'],
            encoding='utf-8'
        )
        file_handler.setLevel(logging.DEBUG)
        
        if DEFAULT_LOG_CONFIG['json_format']:
            file_formatter = JSONFormatter()
        else:
            file_formatter = logging.Formatter(LOG_FORMATS['detailed'])
        
        file_handler.setFormatter(file_formatter)
        logger.addHandler(file_handler)
        
        # 错误文件处理器
        error_handler = logging.handlers.RotatingFileHandler(
            filename=log_dir / 'error.log',
            maxBytes=DEFAULT_LOG_CONFIG['max_file_size'],
            backupCount=DEFAULT_LOG_CONFIG['backup_count'],
            encoding='utf-8'
        )
        error_handler.setLevel(logging.ERROR)
        error_handler.setFormatter(file_formatter)
        logger.addHandler(error_handler)
        
        # 分类文件处理器
        if category in LOG_CATEGORIES:
            category_handler = logging.handlers.RotatingFileHandler(
                filename=log_dir / f'{LOG_CATEGORIES[category]}.log',
                maxBytes=DEFAULT_LOG_CONFIG['max_file_size'],
                backupCount=DEFAULT_LOG_CONFIG['backup_count'],
                encoding='utf-8'
            )
            category_handler.setLevel(logging.DEBUG)
            category_handler.addFilter(CategoryFilter(category))
            category_handler.setFormatter(file_formatter)
            logger.addHandler(category_handler)

class AppLogger:
    """应用日志记录器包装类"""
    
    def __init__(self, name: str, category: str = 'SYSTEM'):
        self.logger = LoggerFactory.get_logger(name, category)
        self.category = category
    
    def _log(self, level: str, message: str, **kwargs):
        """内部日志记录方法"""
        extra_data = kwargs.copy()
        
        # 创建日志记录
        record = self.logger.makeRecord(
            name=self.logger.name,
            level=LOG_LEVELS[level],
            fn='',
            lno=0,
            msg=message,
            args=(),
            exc_info=None
        )
        
        # 添加分类和额外数据
        record.category = self.category
        if extra_data:
            record.extra_data = extra_data
        
        self.logger.handle(record)
    
    def debug(self, message: str, **kwargs):
        """记录DEBUG级别日志"""
        self._log('DEBUG', message, **kwargs)
    
    def info(self, message: str, **kwargs):
        """记录INFO级别日志"""
        self._log('INFO', message, **kwargs)
    
    def warning(self, message: str, **kwargs):
        """记录WARNING级别日志"""
        self._log('WARNING', message, **kwargs)
    
    def error(self, message: str, **kwargs):
        """记录ERROR级别日志"""
        self._log('ERROR', message, **kwargs)
    
    def critical(self, message: str, **kwargs):
        """记录CRITICAL级别日志"""
        self._log('CRITICAL', message, **kwargs)

# 便捷函数
def get_database_logger(module_name: str) -> AppLogger:
    """获取数据库日志记录器"""
    return AppLogger(module_name, 'DATABASE')

def get_api_logger(module_name: str) -> AppLogger:
    """获取API日志记录器"""
    return AppLogger(module_name, 'API')

def get_user_logger(module_name: str) -> AppLogger:
    """获取用户交互日志记录器"""
    return AppLogger(module_name, 'USER')

def get_system_logger(module_name: str) -> AppLogger:
    """获取系统日志记录器"""
    return AppLogger(module_name, 'SYSTEM')

def get_business_logger(module_name: str) -> AppLogger:
    """获取业务日志记录器"""
    return AppLogger(module_name, 'BUSINESS')

def get_query_logger(module_name: str) -> AppLogger:
    """获取查询日志记录器"""
    return AppLogger(module_name, 'USER')